﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace MadProps.Tests.PropChangedTests
{
    [TestClass]
    public class can_handle_direct_reference_to_grandchild
    {
        public class Parent : BaseModel
        {
            public readonly IProp<Child> Child;
            public readonly IProp<Grandchild> Grandchild;
        }

        public class Child : BaseModel
        {
            public readonly IProp<Grandchild> Grandchild;
        }

        public class Grandchild : BaseModel
        {
            public readonly IProp<int> AnInt;
        }

        [TestMethod]
        public void MyTestMethod()
        {
            var parent = new Parent();
            var child = new Child();
            var grandchild = new Grandchild();
            int count = 0;

            // Hook up parent to child
            parent.Child.Value = child;
            Assert.AreEqual(1, parent.Recorder.ChangeCountFor(parent.Child));
            Assert.AreEqual(++count, parent.Recorder.Total);

            // Hook up child to grandchild
            child.Grandchild.Value = grandchild;
            Assert.AreEqual(1, parent.Recorder.ChangeCountFor(child.Grandchild));
            Assert.AreEqual(++count, parent.Recorder.Total);

            // Hook up parent directly to grandchild
            parent.Grandchild.Value = grandchild;
            Assert.AreEqual(1, parent.Recorder.ChangeCountFor(parent.Grandchild));
            Assert.AreEqual(++count, parent.Recorder.Total);

            // PropChange on the grandchild
            grandchild.AnInt.Value = 235;
            Assert.AreEqual(1, parent.Recorder.ChangeCountFor(grandchild.AnInt));
            Assert.AreEqual(++count, parent.Recorder.Total);

            // Disconnect direct reference...
            parent.Grandchild.Value = null;
            Assert.AreEqual(++count, parent.Recorder.Total);

            // ...but still cascade via child.
            grandchild.AnInt.Value = 892;
            Assert.AreEqual(2, parent.Recorder.ChangeCountFor(grandchild.AnInt));
            Assert.AreEqual(++count, parent.Recorder.Total);

            // Disconnect child...
            parent.Child.Value = null;
            Assert.AreEqual(++count, parent.Recorder.Total);

            // ...and the change is no longer seen
            grandchild.AnInt.Value = 3498;
            Assert.AreEqual(2, parent.Recorder.ChangeCountFor(grandchild.AnInt));
            Assert.AreEqual(count, parent.Recorder.Total);
        }
    }
}
